        <!DOCTYPE html>
        <html>
        <head>
                <meta charset="utf-8">
        <title>Distance class / box2d Library / Dart Documentation</title>
        <link rel="stylesheet" type="text/css"
            href="../styles.css">
        <link href="http://fonts.googleapis.com/css?family=Open+Sans:400,600,700,800" rel="stylesheet" type="text/css">
        <link rel="shortcut icon" href="../favicon.ico">
        
        </head>
        <body data-library="box2d" data-type="Distance">
        <div class="page">
        <div class="header">
          <a href="../index.html"><div class="logo"></div></a>
          <a href="../index.html">Dart Documentation</a>
         &rsaquo; <a href="../box2d.html">box2d</a> &rsaquo; <a href="../box2d/Distance.html">Distance</a>        <div id="search-box">
          <input type="search" name="q" id="q" autocomplete="off"
              class="search-input" placeholder="Search API">
        </div>
        
      </div>
      <div class="drop-down" id="drop-down"></div>
      
        <div class="nav">
        
</div>
<div class="content">
        <h2><strong>Distance</strong>
          class
        </h2>
        
<button id="show-inherited" class="show-inherited">Hide inherited</button>
<div class="doc">
<pre class="source">
class Distance {
 int calls;
 int iters;
 int maxIters;

 /** Pool variables for use in distance calculation. */
 Simplex simplex;
 List&lt;int&gt; saveA;
 List&lt;int&gt; saveB;
 vec2 closestPoint;
 vec2 searchDirection;
 vec2 temp;
 vec2 normal;

 /**
  * Construct a new Distance object. For internal use only. Don't directly
  * invoke.
  */
 Distance._construct() :
   simplex = new Simplex(),
   saveA = new List&lt;int&gt;(3),
   saveB = new List&lt;int&gt;(3),
   closestPoint = new vec2.zero(),
   searchDirection = new vec2.zero(),
   temp = new vec2.zero(),
   normal = new vec2.zero(),
   calls = 0,
   iters = 0,
   maxIters = 20 { }

 /**
  * Compute the closest points between two shapes. Supports any combination of:
  * CircleShape and PolygonShape. The simplex cache is input/output.
  * On the first call set SimplexCache.count to zero.
  */
 void computeDistance(DistanceOutput output, SimplexCache cache,
     DistanceInput input) {
   calls++;

   final DistanceProxy proxyA = input.proxyA;
   final DistanceProxy proxyB = input.proxyB;

   Transform transformA = input.transformA;
   Transform transformB = input.transformB;

   // Initialize the simplex.
   simplex.readCache(cache, proxyA, transformA, proxyB, transformB);

   // Get simplex vertices as an array.
   List&lt;SimplexVertex&gt; vertices = simplex.vertices;

   // These store the vertices of the last simplex so that we
   // can check for duplicates and prevent cycling.
   // (pooled above)
   int saveCount = 0;

   simplex.getClosestPoint(closestPoint);
   num distanceSqr1 = closestPoint.length2;
   num distanceSqr2 = distanceSqr1;

   // Main iteration loop
   int iter = 0;
   while (iter &lt; maxIters) {

     // Copy simplex so we can identify duplicates.
     saveCount = simplex.count;
     for (int i = 0; i &lt; saveCount; i++) {
       saveA[i] = vertices[i].indexA;
       saveB[i] = vertices[i].indexB;
     }

     switch (simplex.count) {
       case 1 :
         break;
       case 2 :
         simplex.solve2();
         break;
       case 3 :
         simplex.solve3();
         break;
       default :
         assert (false);
         return;
     }

     // If we have 3 points, then the origin is in the corresponding triangle.
     if (simplex.count == 3)
       break;

     // Compute closest point.
     simplex.getClosestPoint(closestPoint);
     distanceSqr2 = closestPoint.length2;

     distanceSqr1 = distanceSqr2;

     // get search direction;
     simplex.getSearchDirection(searchDirection);

     // Ensure the search direction is numerically fit.
     if (searchDirection.length2 &lt; Settings.EPSILON * Settings.EPSILON) {
       // The origin is probably contained by a line segment
       // or triangle. Thus the shapes are overlapped.

       // We can't return zero here even though there may be overlap.
       // In case the simplex is a point, segment, or triangle it is difficult
       // to determine if the origin is contained in the CSO or very close to
       // it.
       break;
     }

     // Compute a tentative new simplex vertex using support points.
     SimplexVertex vertex = vertices[simplex.count];

     transformA.rotation.transposed().transformed(searchDirection.negate(), temp);
     vertex.indexA = proxyA.getSupport(temp);
     Transform.mulToOut(transformA, proxyA.vertices[vertex.indexA], vertex.wA);
     // Vec2 wBLocal;
     transformB.rotation.transposed().transformed(searchDirection.negate(), temp);
     vertex.indexB = proxyB.getSupport(temp);
     Transform.mulToOut(transformB, proxyB.vertices[vertex.indexB], vertex.wB);
     vertex.w.copyFrom(vertex.wB).sub(vertex.wA);

     // Iteration count is equated to the number of support point calls.
     ++iter;
     ++iters;

     // Check for duplicate support points. This is the main termination
     // criteria.
     bool duplicate = false;
     for (int i = 0; i &lt; saveCount; ++i) {
       if (vertex.indexA == saveA[i] &amp;&amp; vertex.indexB == saveB[i]) {
         duplicate = true;
         break;
       }
     }

     // If we found a duplicate support point we must exit to avoid cycling.
     if (duplicate)
       break;

     // New vertex is ok and needed.
     ++simplex.count;
   }

   maxIters = math.max(maxIters, iter);

   // Prepare output.
   simplex.getWitnessPoints(output.pointA, output.pointB);
   output._distance = distance(output.pointA, output.pointB);
   output.iterations = iter;

   // Cache the simplex.
   simplex.writeCache(cache);

   // Apply radii if requested.
   if (input.useRadii) {
     num rA = proxyA.radius;
     num rB = proxyB.radius;

     if (output._distance &gt; rA + rB &amp;&amp; output._distance &gt; Settings.EPSILON) {
       // Shapes are still no overlapped.
       // Move the witness points to the outer surface.
       output._distance -= rA + rB;
       normal.copyFrom(output.pointB).sub(output.pointA);
       normal.normalize();
       temp.copyFrom(normal).scale(rA);
       output.pointA.add(temp);
       temp.copyFrom(normal).scale(rB);
       output.pointB.sub(temp);
     } else {
       // Shapes are overlapped when radii are considered.
       // Move the witness points to the middle.
       output.pointA.add(output.pointB).scale(.5);
       output.pointB.copyFrom(output.pointA);
       output._distance = 0.0;
     }
   }
 }
}
</pre>
</div>
<div>
<h3>Properties</h3>
<div class="field"><h4 id="calls">
<button class="show-code">Code</button>
int         <strong>calls</strong> <a class="anchor-link"
            href="#calls"
            title="Permalink to Distance.calls">#</a>
        </h4>
        <div class="doc">
<pre class="source">
calls
</pre>
</div>
</div>
<div class="field"><h4 id="closestPoint">
<button class="show-code">Code</button>
<a href="../vector_math/vec2.html">vec2</a>         <strong>closestPoint</strong> <a class="anchor-link"
            href="#closestPoint"
            title="Permalink to Distance.closestPoint">#</a>
        </h4>
        <div class="doc">
<pre class="source">
closestPoint
</pre>
</div>
</div>
<div class="field"><h4 id="iters">
<button class="show-code">Code</button>
int         <strong>iters</strong> <a class="anchor-link"
            href="#iters"
            title="Permalink to Distance.iters">#</a>
        </h4>
        <div class="doc">
<pre class="source">
iters
</pre>
</div>
</div>
<div class="field"><h4 id="maxIters">
<button class="show-code">Code</button>
int         <strong>maxIters</strong> <a class="anchor-link"
            href="#maxIters"
            title="Permalink to Distance.maxIters">#</a>
        </h4>
        <div class="doc">
<pre class="source">
maxIters
</pre>
</div>
</div>
<div class="field"><h4 id="normal">
<button class="show-code">Code</button>
<a href="../vector_math/vec2.html">vec2</a>         <strong>normal</strong> <a class="anchor-link"
            href="#normal"
            title="Permalink to Distance.normal">#</a>
        </h4>
        <div class="doc">
<pre class="source">
normal
</pre>
</div>
</div>
<div class="field"><h4 id="saveA">
<button class="show-code">Code</button>
List&lt;int&gt;         <strong>saveA</strong> <a class="anchor-link"
            href="#saveA"
            title="Permalink to Distance.saveA">#</a>
        </h4>
        <div class="doc">
<pre class="source">
saveA
</pre>
</div>
</div>
<div class="field"><h4 id="saveB">
<button class="show-code">Code</button>
List&lt;int&gt;         <strong>saveB</strong> <a class="anchor-link"
            href="#saveB"
            title="Permalink to Distance.saveB">#</a>
        </h4>
        <div class="doc">
<pre class="source">
saveB
</pre>
</div>
</div>
<div class="field"><h4 id="searchDirection">
<button class="show-code">Code</button>
<a href="../vector_math/vec2.html">vec2</a>         <strong>searchDirection</strong> <a class="anchor-link"
            href="#searchDirection"
            title="Permalink to Distance.searchDirection">#</a>
        </h4>
        <div class="doc">
<pre class="source">
searchDirection
</pre>
</div>
</div>
<div class="field"><h4 id="simplex">
<button class="show-code">Code</button>
<a href="../box2d/Simplex.html">Simplex</a>         <strong>simplex</strong> <a class="anchor-link"
            href="#simplex"
            title="Permalink to Distance.simplex">#</a>
        </h4>
        <div class="doc">
<pre class="source">
simplex
</pre>
</div>
</div>
<div class="field"><h4 id="temp">
<button class="show-code">Code</button>
<a href="../vector_math/vec2.html">vec2</a>         <strong>temp</strong> <a class="anchor-link"
            href="#temp"
            title="Permalink to Distance.temp">#</a>
        </h4>
        <div class="doc">
<pre class="source">
temp
</pre>
</div>
</div>
</div>
<div>
<h3>Methods</h3>
<div class="method"><h4 id="computeDistance">
<button class="show-code">Code</button>
void <strong>computeDistance</strong>(<a href="../box2d/DistanceOutput.html">DistanceOutput</a> output, <a href="../box2d/SimplexCache.html">SimplexCache</a> cache, <a href="../box2d/DistanceInput.html">DistanceInput</a> input) <a class="anchor-link" href="#computeDistance"
              title="Permalink to Distance.computeDistance">#</a></h4>
<div class="doc">
<p>Compute the closest points between two shapes. Supports any combination of:
CircleShape and PolygonShape. The simplex cache is input/output.
On the first call set SimplexCache.count to zero.</p>
<pre class="source">
void computeDistance(DistanceOutput output, SimplexCache cache,
   DistanceInput input) {
 calls++;

 final DistanceProxy proxyA = input.proxyA;
 final DistanceProxy proxyB = input.proxyB;

 Transform transformA = input.transformA;
 Transform transformB = input.transformB;

 // Initialize the simplex.
 simplex.readCache(cache, proxyA, transformA, proxyB, transformB);

 // Get simplex vertices as an array.
 List&lt;SimplexVertex&gt; vertices = simplex.vertices;

 // These store the vertices of the last simplex so that we
 // can check for duplicates and prevent cycling.
 // (pooled above)
 int saveCount = 0;

 simplex.getClosestPoint(closestPoint);
 num distanceSqr1 = closestPoint.length2;
 num distanceSqr2 = distanceSqr1;

 // Main iteration loop
 int iter = 0;
 while (iter &lt; maxIters) {

   // Copy simplex so we can identify duplicates.
   saveCount = simplex.count;
   for (int i = 0; i &lt; saveCount; i++) {
     saveA[i] = vertices[i].indexA;
     saveB[i] = vertices[i].indexB;
   }

   switch (simplex.count) {
     case 1 :
       break;
     case 2 :
       simplex.solve2();
       break;
     case 3 :
       simplex.solve3();
       break;
     default :
       assert (false);
       return;
   }

   // If we have 3 points, then the origin is in the corresponding triangle.
   if (simplex.count == 3)
     break;

   // Compute closest point.
   simplex.getClosestPoint(closestPoint);
   distanceSqr2 = closestPoint.length2;

   distanceSqr1 = distanceSqr2;

   // get search direction;
   simplex.getSearchDirection(searchDirection);

   // Ensure the search direction is numerically fit.
   if (searchDirection.length2 &lt; Settings.EPSILON * Settings.EPSILON) {
     // The origin is probably contained by a line segment
     // or triangle. Thus the shapes are overlapped.

     // We can't return zero here even though there may be overlap.
     // In case the simplex is a point, segment, or triangle it is difficult
     // to determine if the origin is contained in the CSO or very close to
     // it.
     break;
   }

   // Compute a tentative new simplex vertex using support points.
   SimplexVertex vertex = vertices[simplex.count];

   transformA.rotation.transposed().transformed(searchDirection.negate(), temp);
   vertex.indexA = proxyA.getSupport(temp);
   Transform.mulToOut(transformA, proxyA.vertices[vertex.indexA], vertex.wA);
   // Vec2 wBLocal;
   transformB.rotation.transposed().transformed(searchDirection.negate(), temp);
   vertex.indexB = proxyB.getSupport(temp);
   Transform.mulToOut(transformB, proxyB.vertices[vertex.indexB], vertex.wB);
   vertex.w.copyFrom(vertex.wB).sub(vertex.wA);

   // Iteration count is equated to the number of support point calls.
   ++iter;
   ++iters;

   // Check for duplicate support points. This is the main termination
   // criteria.
   bool duplicate = false;
   for (int i = 0; i &lt; saveCount; ++i) {
     if (vertex.indexA == saveA[i] &amp;&amp; vertex.indexB == saveB[i]) {
       duplicate = true;
       break;
     }
   }

   // If we found a duplicate support point we must exit to avoid cycling.
   if (duplicate)
     break;

   // New vertex is ok and needed.
   ++simplex.count;
 }

 maxIters = math.max(maxIters, iter);

 // Prepare output.
 simplex.getWitnessPoints(output.pointA, output.pointB);
 output._distance = distance(output.pointA, output.pointB);
 output.iterations = iter;

 // Cache the simplex.
 simplex.writeCache(cache);

 // Apply radii if requested.
 if (input.useRadii) {
   num rA = proxyA.radius;
   num rB = proxyB.radius;

   if (output._distance &gt; rA + rB &amp;&amp; output._distance &gt; Settings.EPSILON) {
     // Shapes are still no overlapped.
     // Move the witness points to the outer surface.
     output._distance -= rA + rB;
     normal.copyFrom(output.pointB).sub(output.pointA);
     normal.normalize();
     temp.copyFrom(normal).scale(rA);
     output.pointA.add(temp);
     temp.copyFrom(normal).scale(rB);
     output.pointB.sub(temp);
   } else {
     // Shapes are overlapped when radii are considered.
     // Move the witness points to the middle.
     output.pointA.add(output.pointB).scale(.5);
     output.pointB.copyFrom(output.pointA);
     output._distance = 0.0;
   }
 }
}
</pre>
</div>
</div>
</div>
        </div>
        <div class="clear"></div>
        </div>
        <div class="footer">
          
        </div>
        <script async src="../client-live-nav.js"></script>
        </body></html>
        
